// This is the main DLL file.

#include "stdafx.h"
#include <stdio.h>
#include <string.h>
#include <Windows.h>

#include "Toolbox.h"

#define GOOD 0
#define BAD  1

using namespace System::Runtime::InteropServices;
using namespace System::Globalization;

using namespace Tradex;

namespace Tradex {
	namespace Connectivity {
		namespace Rithmic {

			ToolBox::ToolBox () {
				_Epoch = DateTime (1970, 1, 1, 0, 0, 0, DateTimeKind::Utc);
			}

			sNCharcb ToolBox::CreateRString (String^ input) {
				sNCharcb rString = sNCharcb ();
				if (!String::IsNullOrEmpty(input)) {
					rString.pData = (char*)(void*) Marshal::StringToHGlobalAnsi(input);
					rString.iDataLen = input->Length;
				}
				return rString;
			}

			void ToolBox::CreateRTimeStamp (DateTime input, int* pEpochSeconds, int* pMicroSeconds) {
				TimeSpan span = input - _Epoch;
				int epochSeconds = (int) span.TotalSeconds;
				int microSeconds = (int) ((span.Ticks - (epochSeconds * TimeSpan::TicksPerSecond))/10);
				
				if (pEpochSeconds != nullptr) {
					*pEpochSeconds = epochSeconds;
				}
				if (pMicroSeconds != nullptr) {
					*pMicroSeconds = microSeconds;
				}

				// Check: we regenerate the DateTime to see if it matches.
				DateTime round = ToolBox::CreateNDateTime (epochSeconds, microSeconds);
				Console::WriteLine (
					String::Format (CultureInfo::InvariantCulture,
					"From {0} to {1}", input, round)
				);
			}

			void ToolBox::DestroyRString (sNCharcb* rString) {
				if (rString->pData != NULL) {
					Marshal::FreeHGlobal(IntPtr(rString->pData));
					rString->pData = 0;
					rString->iDataLen = 0;
				}
			}

			void ToolBox::FillRAccountInfo (RApi::AccountInfo* pAccountInfo, AccountKey^ accountKey) {
				array<System::String^>^ pParts;
				pParts = accountKey->Account->Split('/');
				pAccountInfo->sFcmId = ToolBox::CreateRString (pParts[0]);
				pAccountInfo->sIbId = ToolBox::CreateRString (pParts[1]);
				pAccountInfo->sAccountId = ToolBox::CreateRString (pParts[2]);
			}

			void ToolBox::ClearRAccountInfo (RApi::AccountInfo* pAccountInfo) {
				ToolBox::DestroyRString (&pAccountInfo->sAccountId);
				ToolBox::DestroyRString (&pAccountInfo->sFcmId);
				ToolBox::DestroyRString (&pAccountInfo->sIbId);
			}

			DateTime ToolBox::CreateNDateTime (int epochSeconds, int microSeconds) {
				DateTime dt = _Epoch.AddSeconds (epochSeconds).AddTicks (microSeconds * 10);
				return dt;
			}

			String^ ToolBox::CreateNString (sNCharcb rString) {
				if (rString.iDataLen != 0) {
					return gcnew System::String (rString.pData, 0, rString.iDataLen);	
				} else {
					return nullptr;
				}
			}

			AccountKey^ ToolBox::CreateTAccountKey (RApi::AccountInfo acctInfo) {
				String^ sAct = CreateNString (acctInfo.sAccountId);
				String^ sIb = ToolBox::CreateNString (acctInfo.sIbId);
				String^ sFcm = ToolBox::CreateNString (acctInfo.sFcmId);
				return gcnew AccountKey (sFcm, sIb, sAct);
			}

		}
	}
}